package com.haotian.coder.service.Impl;

import cn.hutool.core.util.StrUtil;
import com.haotian.coder.constant.UserConstant;
import com.haotian.coder.exception.BusinessException;
import com.haotian.coder.exception.ErrorCode;
import com.haotian.coder.exception.ThrowUtils;
import com.haotian.coder.mapper.ChatHistoryMapper;
import com.haotian.coder.model.dto.chatHistory.ChatHistoryQueryRequest;
import com.haotian.coder.model.entity.App;
import com.haotian.coder.model.entity.ChatHistory;
import com.haotian.coder.model.entity.User;
import com.haotian.coder.model.enums.ChatHistoryMessageTypeEnum;
import com.haotian.coder.service.AppService;
import com.haotian.coder.service.ChatHistoryService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 对话历史 服务层实现。
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 */
@Slf4j
@Service
public class ChatHistoryServiceImpl extends ServiceImpl<ChatHistoryMapper, ChatHistory> implements ChatHistoryService {

    @Resource
    @Lazy
    private AppService appService;
    @Override
    public boolean addChatMessage(Long appId, String message, String messageType, Long userId) {
        // 基础校验
        ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用未生成！");
        ThrowUtils.throwIf(StrUtil.isBlank(message), ErrorCode.PARAMS_ERROR, "用户消息不能空！");
        ThrowUtils.throwIf(userId == null || userId <= 0, ErrorCode.PARAMS_ERROR, "用户 ID 不能空！");
        ThrowUtils.throwIf(StrUtil.isBlank(messageType), ErrorCode.PARAMS_ERROR, "信息类型不能为空！");
        // 信息类型校验，防止随意传参
        ChatHistoryMessageTypeEnum messageEnum = ChatHistoryMessageTypeEnum.getEnumByValue(messageType);
        if (messageEnum == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "信息类型错误");
        }
        // 构建对象，传入数据库
        ChatHistory chatHistory = ChatHistory.builder().appId(appId).message(message).messageType(messageType).userId(userId).build();
        return this.save(chatHistory);
    }

    @Override
    public boolean deleteByappId(Long appId) {
        ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用未生成！");
        QueryWrapper deleteWrapper = new QueryWrapper().eq(ChatHistory::getAppId, appId);
        return this.remove(deleteWrapper);
    }

    /**
     * 获取查询包装类
     *
     * @param chatHistoryQueryRequest
     * @return
     */
    @Override
    public QueryWrapper getQueryWrapper(ChatHistoryQueryRequest chatHistoryQueryRequest) {
        QueryWrapper queryWrapper = QueryWrapper.create();
        if (chatHistoryQueryRequest == null) {
            return queryWrapper;
        }
        Long id = chatHistoryQueryRequest.getId();
        String message = chatHistoryQueryRequest.getMessage();
        String messageType = chatHistoryQueryRequest.getMessageType();
        Long appId = chatHistoryQueryRequest.getAppId();
        Long userId = chatHistoryQueryRequest.getUserId();
        LocalDateTime lastCreateTime = chatHistoryQueryRequest.getLastCreateTime();
        String sortField = chatHistoryQueryRequest.getSortField();
        String sortOrder = chatHistoryQueryRequest.getSortOrder();
        // 拼接查询条件
        queryWrapper.eq("id", id)
                .like("message", message)
                .eq("messageType", messageType)
                .eq("appId", appId)
                .eq("userId", userId);
        // 游标查询逻辑 - 只使用 createTime 作为游标
        if (lastCreateTime != null) {
            queryWrapper.lt("createTime", lastCreateTime);
        }
        // 排序
        if (StrUtil.isNotBlank(sortField)) {
            queryWrapper.orderBy(sortField, "ascend".equals(sortOrder));
        } else {
            // 默认按创建时间降序排列
            queryWrapper.orderBy("createTime", false);
        }
        return queryWrapper;
    }

    @Override
    public Page<ChatHistory> listAppChatHistoryByPage(Long appID, int pageSize, LocalDateTime localDateTime, User loginUser) {
        // 基本参数校验
        ThrowUtils.throwIf(appID == null || appID <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空！");
        ThrowUtils.throwIf(pageSize <= 0 || pageSize>50, ErrorCode.PARAMS_ERROR, "分页大小应1-50页之间！");
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR,"用户不存在");
        // 权限校验，只有本人或者管理员才可以查询
        App app = appService.getById(appID);
        Long appUserId = app.getUserId();
        Long loginUserID = loginUser.getId();
        if (!appUserId.equals(loginUserID) && !UserConstant.ADMIN_ROLE.equals(loginUser.getUserRole())){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR,"无权限查看！");
        }
        // 构建查询条件
        ChatHistoryQueryRequest chatHistoryQueryRequest = new ChatHistoryQueryRequest();
        chatHistoryQueryRequest.setAppId(appID);
        chatHistoryQueryRequest.setLastCreateTime(localDateTime);
        QueryWrapper queryWrapper = getQueryWrapper(chatHistoryQueryRequest);
        // 返回结果
        return this.page(Page.of(1, pageSize), queryWrapper);
    }

    @Override
    public int loadHistoryMemory(Long appId, MessageWindowChatMemory chatMemory, int maxCount){
        try {
            // 构造查询条件，按照时间排序，起始的页号为1，排除用户的信息
            QueryWrapper queryWrapper = new QueryWrapper()
                    .eq("appId", appId)
                    .eq("messageType", ChatHistoryMessageTypeEnum.USER.getValue())
                    .orderBy("createTime", true)
                    .limit(1, maxCount);  // 偏移量，每页最大记录数

            List<ChatHistory> historyList = this.list(queryWrapper);
            // 反转列表，保证老的数据在前
            historyList = historyList.reversed();
            // 按照时间顺序，将信息添加到记忆chatMemory中
            int loadCount = 0;
            // 清理缓存，防止重复加载
            chatMemory.clear();
            for (ChatHistory history : historyList){
                if (history.getMessageType().equals(ChatHistoryMessageTypeEnum.AI.getValue())){
                    chatMemory.add(AiMessage.from(history.getMessage()));
                    loadCount++;
                }else if (history.getMessageType().equals(ChatHistoryMessageTypeEnum.USER.getValue())){
                    chatMemory.add(UserMessage.from(history.getMessage()));
                    loadCount++;
                }
            }
            // 返回记忆的数量
            log.info("加载历史记忆成功，appID为{},数量{}：", appId,loadCount);
            return loadCount;
        } catch (Exception e) {
            log.error("appid:{},加载记忆失败，{}",appId, e.getMessage());
        }
        return 0;
    }
}